<?php

namespace app\admin\model\inventory;

use think\Model;
use traits\model\SoftDelete;
use app\admin\model\inventory\MaterialList;
use think\Log;
use think\Db;
use app\common\model\Inventory;
use think\Exception;
use app\api\controller\Wms;
use app\admin\model\Kisapi;
use app\admin\model\information\KisBaseinfo;

class Material extends Model
{

    //use SoftDelete;

    // 表名
    protected $name = 'material';
    
    // 自动写入时间戳字段
    protected $autoWriteTimestamp = 'datetime';

    // 定义时间戳字段名
    protected $createTime = 'createtime';
    protected $updateTime = 'updatetime';
    protected $deleteTime = 'deletetime';

    // 追加属性
    protected $append = [

    ];


    /**
     * 修改领料订单数量，满足条件的关闭
     * @param $source_code
     * @param $row_id
     * @param $fqty
     * @return void
     */
    public static function updateMaterialQty($source_code,$row_id,$fqty){
        $digits = getDigits();
        $material = db('material')->where('material_code',$source_code)->find();
        if(!$material){
            exception("不存在{$source_code}领料单");
        }
        if(!$material['status']){
            exception("{$source_code}领料单已关闭");
        }
        
        $where = [
            'material_code' => $source_code,
            'row_id' => $row_id
        ];
        
        $item = MaterialList::where($where)->find();
        if(!$item){
            Log::error("找不到对应领料单记录:单号{$source_code},行号{$row_id}");
            exception('找不到对应领料单记录');
        }
        
        $no_quantity = round($item->quantity - floatval($item->commit_quantity) , $digits);
        if($no_quantity<=0){
            exception('领料单表体记录待领数量为0');
        }
        
        if($no_quantity<=$fqty){
            //关闭采购单
            $item->status = 0;
            $item->save();
        }
        
        //判断能否整张单关闭
        $check = db('material_list')->where([
            'material_code' => $source_code,
            'status' => 1
        ])
        ->field('id')
        ->find();
        if(!$check){
            //关闭领料单
            db('material')->where('id',$material['id'])->update([
                'status' => 0
            ]);
        }
        
        $item->setInc('commit_quantity',$fqty);
    }
    
    /**
     * 构建查询
     * @return \think\db\Query
     * @throws \think\Exception
     */
    
    public static function getSql()
    {
        $sql = Db::connect('database.sec')->table('MaterialAppVouchs')
        ->alias('m')
        ->join('MaterialAppVouch u','m.ID=u.ID')
        ->field('m.ID,u.cDepCode,u.cRdCode,m.cWhcode,m.iQuantity,m.irowno,m.cInvCode,m.AutoID,u.cCode,u.dVeriDate ,u.dDate')
        ->where([
            'm.cInvCode' => [['like','04%'],['like','08%'], 'or']
        ])
        ->where("u.dVeriDate is not null and (m.fOutQuantity is null or m.fOutQuantity < m.iQuantity)")
        ->where([
            'u.cCloser'=>null,
            'm.cInvCode' => ['not like','0810%']
        ]);
        
        return $sql;
    }
    
    /*
     * 获取发货通知单日期，期间，读配置 kis_fahuo_date_type  销售出库单待审
     * 默认当天
     *   */
    public static function getFahuoCfgDate($kis_fahuo_date_type = ''){
        $startDate = date('Y-m-d',time());
        $endDate = date('Y-m-d',time());
        
        if(config('site.kis_fahuo_date_type')){
            if(!$kis_fahuo_date_type){
                $kis_fahuo_date_type = config('site.kis_fahuo_date_type');
            }
            switch ($kis_fahuo_date_type){
                case 1:
                    $startDate = date("Y-m-d",strtotime("-1 month")); 
                    break;
                case 2:
                    $startDate = date("Y-m-d",strtotime("-2 month")); 
                    break;
                case 3:
                    $startDate = date("Y-m-d",strtotime("-3 month")); 
                    break;
                case 4:
                    $startDate = date("Y-m-d",strtotime("-6 month")); 
                    break;
                case 5:
                    $startDate = date("Y-m-d",strtotime("-12 month")); 
                    break;
                case 6:
                    $startDate = date("Y-m-d",strtotime("-24 month")); 
                    break;
            }
        }
        
        return [
            'StartTime' => $startDate,
            'EndTime' => $endDate
        ];
    }

    /*
     * 获取生产任务材料清单日期，期间，读配置 kis_mlist_date_type
     * 默认当天
     *   */
    public static function getMlistCfgDate(){
        $startDate = date('Y-m-d',time());
        $endDate = date('Y-m-d',time());
        
        if(config('site.kis_mlist_date_type')){
            switch (config('site.kis_mlist_date_type')){
                case 1:
                    $startDate = date("Y-m-d",strtotime("-1 month")); 
                    break;
                case 2:
                    $startDate = date("Y-m-d",strtotime("-2 month")); 
                    break;
                case 3:
                    $startDate = date("Y-m-d",strtotime("-3 month")); 
                    break;
                case 4:
                    $startDate = date("Y-m-d",strtotime("-6 month")); 
                    break;
                case 5:
                    $startDate = date("Y-m-d",strtotime("-12 month")); 
                    break;
            }
        }
        
        return [
            'StartTime' => $startDate,
            'EndTime' => $endDate
        ];
    }

    /**
     * 同步发货通知单数据 type=1
     * $source_code不为空，更新领料单数量
     * 获取销售出库单，未审核，当日 type=3
     */
    public function getMaterialData($source_code = '',$auto_id = '',$type = 1,$param = [])
    {
        set_time_limit(0);
        try {
            $digits = getDigits();
            $materialListModel = new MaterialList();
            $where = [
                'material_code' => $source_code
            ];
            if($source_code){
                if($auto_id){
                    $where['auto_id'] = $auto_id;
                }
                $newList = $materialListModel::where($where)->select();
                if($newList){
                    foreach ($newList as $mitem){
                        $temp_sum_qty = db('temporary')->where([
                            'source_code'=>$mitem->material_code,
                            //'order_list'=> ['IN',[2,15]],//材料出库（生产）、销售出库
                            'number'=>$mitem->inventory_number,
                            'row_id'=>$mitem->row_id,
                            'status'=>['IN',[0,1]]
                        ])->sum('quantity',0);
                        
                        $mitem->commit_quantity = round($temp_sum_qty,$digits);
                        $no_quantity = $mitem->quantity-$mitem->commit_quantity;
                        if ($no_quantity<=0){
                            $mitem->status = 0;//关闭
                            $mitem->close_time = date('Y-m-d', time());
                        }else{
                            $mitem->status = 1;//开启
                            $mitem->close_time = null;
                        }
                        $mitem->save();
                    }
                }
            }else{
                //领料任务
                //获取配置日期
                $condition = [
                    'PageSize'=>1,
                    'PageIndex'=>1,
                    "fStatus"=>"1,2,3"
                ];

                $api_name = 'getBillSEOutStockList';
                if($type==1){//KIS发货通知单
                    if($param){
                        //按1个月1个月取数
                        $date_arr = $param;
                    }else{
                        //手动点的，默认近1个月
                        $date_arr = self::getFahuoCfgDate(1);
                    }
                    $customer_arr = KisBaseinfo::getCustomer(false,false,[],true);
                    $departmetn_arr = KisBaseinfo::getDepartment();
                    $unit_arr = KisBaseinfo::getUnit();
                }else if($type == 2){//KIS生产任务材料清单
                    $date_arr = self::getMlistCfgDate();
                    $api_name = 'getIcmoList';
                }else if($type == 3){//KIS销售出库单
                    $date_arr = [
                        "fAcctNum" => "001",//味业账套
                        "fTrantype" => 21,
                        "fStatus" => "0",
                        "StartTime" => date('Y-m-d',time()),
                        "EndTime" => date('Y-m-d' , strtotime('+1 day')),   //明天  查当天的单
                    ];
                    $date = self::getFahuoCfgDate();
                    if($date){
                        $date_arr = array_merge($date_arr,$date);
                    }

                    $api_name = 'getIcStockList';
                    $customer_arr = KisBaseinfo::getCustomer(false,false,[],true);
                    $departmetn_arr = KisBaseinfo::getDepartment();
                    $unit_arr = KisBaseinfo::getUnit();
                }

                $condition = array_merge($condition,$date_arr);
                $row = Kisapi::getDataByName($api_name,$condition,true);
                
                $count = 0;
                if(isset($row['data_totle'])){
                    $count = $row['data_totle'];
                }

                if(!$count){
                    //不去掉，无法删除pda单据，会提示这句
                    //exception("已经最新数据，没有数据可以同步");
                }
                
                //取数
                $newList =[];
                if($count>1000) {
                    for($i=1;$i<=(intval($count/1000)+1);$i++){
                        $condition['PageSize'] = 1000;
                        $condition['PageIndex'] = $i;
                        $data = Kisapi::getDataByName($api_name,$condition,true);
                        $newList = array_merge($newList,$data);
                    }
                }else{
                    $condition['PageSize'] = 1000;
                    $newList = Kisapi::getDataByName($api_name,$condition,true);
                }
                
                if(empty($newList)||!isset($newList['data_item'])){
                    exception("已经最新数据，没有数据可以同步");
                }
                
                $material_arr = [];//本地出库任务表头
                $material_list_arr = [];//本地出库任务表体
                $now = date('Y-m-d',time());

                if($newList){
                    foreach ($newList['data_item'] as $head) {
                        if($type==1){//KIS发货通知单
                            $body = $head['t_SEOutStockEntry'];
                            unset($head['t_SEOutStockEntry']);
                        }else if($type==2){//KIS生产任务材料清单
                            $body = Kisapi::getDataByName('getPPBOM',['fBillNo'=>$head['FBillNo']]);
                            if(!$body){
                                Log::error("生产任务单{$head['FBillNo']},材料清单为空");
                            }
                        }else if($type==3){
                            $body = $head['icstockbillentry'];
                            unset($head['icstockbillentry']);
                        }

                        if(!$body){
                            continue;
                        }
                        
                        if($type==1){//KIS发货通知单
                            $temp_marr = [
                                'fInterId' => $head['fInterId'],
                                'source_code' => $head['fInterId'],//销售订单内码
                                'material_code' => $head['fBillNo'],//发货单号
                                'order_date' => substr($head['fDate'],0,10),
                                'crdname' => '发货通知',
                                'crdcode' => 83,//$head['fSelTranType'],
                                'cdepcode' => $head['fDeptId'],
                                'cdepname' => isset($departmetn_arr[$head['fDeptId']])?$departmetn_arr[$head['fDeptId']]:'',
                                'cUser_Id' => $head['fCustID'],//这里是客户
                                'cUser_Name' => isset($customer_arr[$head['fCustID']])?$customer_arr[$head['fCustID']]:'',
                                'source' => 2,//KIS
                                'sh_time' => substr($head['fCheckDate'],0,10),
                                'remark' => $head['fExplanation'],
                                'createtime' => $now,
                                'fCustID' => $head['fCustID']
                            ];
                        }else if($type==2){//KIS生产任务材料清单
                            $head['fInterId'] = $head['FInterID'];
                            $temp_marr = [
                                'fInterId' => $head['FInterID'],
                                'source_code' => $head['FInterID'],//生产任务单号内码
                                'material_code' => $head['FBillNo'],//生产任务单号
                                'order_date' => substr($head['FPlanCommitDate'],0,10),
                                'crdname' => '材料清单',
                                'crdcode' => $head['FTranType'],
                                'cdepcode' => '',
                                'cdepname' => '',
                                'cUser_Id' => '',
                                'cUser_Name' => '',
                                'source' => 2,//KIS
                                'sh_time' => substr($head['FCheckDate'],0,10),
                                'remark' => "ID:{$head['FItemID']},品名:{$head['FName']},数量:{$head['FQty']}",
                                'createtime' => $now,
                                'fCustID' => 0,
                                'type' => 2
                            ];
                        }else if($type==3){
                            $temp_marr = [
                                'fInterId' => $head['fInterId'],
                                'source_code' => $head['fInterId'],//销售订单内码
                                'material_code' => $head['fBillNo'],//发货单号
                                'order_date' => substr($head['fDate'],0,10),
                                'crdname' => '销售出库单',
                                'crdcode' => 21,
                                'cdepcode' => $head['fDeptId'],
                                'cdepname' => isset($departmetn_arr[$head['fDeptId']])?$departmetn_arr[$head['fDeptId']]:'',
                                'cUser_Id' => $head['fSupplyId'],//这里是客户
                                'cUser_Name' => isset($customer_arr[$head['fSupplyId']])?$customer_arr[$head['fSupplyId']]:'',
                                'source' => 2,//KIS
                                'sh_time' => substr($head['fCheckDate'],0,10),
                                'remark' => $head['fExplanation'],
                                'createtime' => $now,
                                'type' => 3
                            ];
                        }
                        
                        $mid = db('material')->where([
                            'fInterId' => $head['fInterId'],
                            'type' => $type
                        ])->value('id');
                        if($mid){
                            $temp_marr['id'] = $mid;
                        }
                        
                        //本地存在有效单据，跳过
                        if(db('temporary')->where([
                            'source_code' => $head['fBillNo'],
                            //'u8_code' => ['neq','not null'],
                            'status' => [0,1] //过滤掉待复核、已复核
                        ])
                        ->value('id')){
                            continue;
                        }

                        $material_arr[] = $temp_marr;

                        //20240410循环本地销售出库单表体，和金蝶不符的则删除
                        $this_ids_arr = (array)array_column($body,'fDetailID');
                        $auto_id_arr = db('material_list')->where('material_code',$head['fBillNo'])->column('auto_id');
                        if($this_ids_arr&&$auto_id_arr){
                            //循环现有auto_id，无则删除
                            foreach($auto_id_arr as $procure_auto_id){
                                if(!in_array($procure_auto_id,$this_ids_arr)){
                                    db('material_list')->where([
                                        'material_code' => $head['fBillNo'],
                                        'auto_id' => $procure_auto_id
                                    ])
                                    ->delete();
                                }
                            }
                        }
                        //

                        foreach ($body as $k=>$value){
                            if($type==1){//KIS发货通知单
                                //发出数量>=订单数，则跳过
                                if($value['fCommitQty']>=$value['fQty']){
                                    continue;
                                }

                                $inventory = Inventory::get([
                                    'number' => $value['fNumber']
                                    //$value['fItemId']
                                ]);
                                $temp_ml_arr = [
                                    'fInterId' => $head['fInterId'],
                                    'auto_id' => $value['fDetailID'],
                                    'inv_id' => $inventory->id,
                                    'material_code' => $head['fBillNo'],
                                    'row_id' => $value['fEntryId'],
                                    'inventory_number' => @$inventory->number,
                                    'inventory_name' => $value['fName'],
                                    'quantity' => $value['fQty'],
                                    'commit_quantity' => $value['fCommitQty'],
                                    'fAuxQty' => $value['fAuxQty'],
                                    'fAuxPrice' => $value['fAuxPrice'],//含税单价
                                    'fPrice' => $value['fPrice'],//单价
                                    'fAmount' => $value['fAmount'],//总价
                                    'fUnitId' => $value['fUnitId'],
                                    'fUnitName' => isset($unit_arr[$value['fUnitId']])?$unit_arr[$value['fUnitId']]:'',
                                    'cBatch' => $value['fBatchNo'],
                                    'remark' => $value['fNote'],
                                    'fOrderBillNo' => $value['fOrderBillNo'],
                                    'fOrderInterID' => $value['fOrderInterID'],
                                    'fOrderEntryID' => $value['fOrderEntryID'],
                                    'createtime'=>date('Y-m-d H:i:s',time())
                                ];
                            }else if($type==2){//KIS生产任务材料清单
                                $temp_ml_arr = [
                                    'fInterId' => $head['FInterID'],
                                    'auto_id' => $k+1,
                                    'inv_id' => $value['FItemID'],
                                    'material_code' => $head['FBillNo'],
                                    'row_id' => $k+1,
                                    'inventory_number' => $value['FNumber'],
                                    'inventory_name' => $value['FName'],
                                    'quantity' => $value['FPPomQty'],
                                    'fAuxQty' => $value['FPPomAuxQty'],
                                    'fAuxPrice' => 0,
                                    'fPrice' => 0,//单价
                                    'fAmount' => 0,//总价
                                    'fUnitId' => $value['FUnitID'],
                                    'fUnitName' => $value['FUnitName'],
                                    'cBatch' => $value['FBatchNo'],
                                    'remark' => '',
                                    'type' => 2,
                                    'fOrderBillNo' => $head['FBillNo'],
                                    'createtime'=>date('Y-m-d H:i:s',time())
                                ];

                                $value['fDetailID'] = $k+1;//方便下面搜索
                                $value['fEntryId'] = $k+1;
                                $value['fItemId'] = $value['FItemID'];
                            }else if($type==3){
                                $temp_ml_arr = [
                                    'fInterId' => $head['fInterId'],
                                    'auto_id' => $value['fDetailID'],
                                    'inv_id' => $value['fItemId'],
                                    'material_code' => $head['fBillNo'],
                                    'row_id' => $value['fEntryId'],
                                    'inventory_number' => $value['fNumber'],
                                    'inventory_name' => $value['fName'],
                                    'quantity' => $value['fQty'],
                                    'commit_quantity' => 0,
                                    'fAuxQty' => $value['fAuxQty'],
                                    'fAuxPrice' => $value['fAuxPrice'],//含税单价00
                                    'fPrice' => $value['fPrice'],//单价
                                    'fAmount' => $value['fAmount'],//总价
                                    'fUnitId' => $value['fUnitId'],
                                    'fUnitName' => isset($unit_arr[$value['fUnitId']])?$unit_arr[$value['fUnitId']]:'',
                                    'cBatch' => $value['fBatchNo'],
                                    'remark' => $value['fNote'],
                                    'status' => 1,//同步下来的，都是待审核的
                                    'fOrderBillNo' => $value['fOrderBillNo'],//销售订单 源单
                                    'fOrderInterID' => $value['fOrderInterID'],
                                    'fOrderEntryID' => $value['fOrderEntryID'],

                                    'fSourceBillNo' => $value['fSourceBillNo'],//发货通知单 源单
                                    'fsourceinterid' => $value['fsourceinterid'],
                                    'fSourceEntryID' => $value['fSourceEntryID'],
                                    'createtime'=>date('Y-m-d H:i:s',time()),
                                    'type' => 3
                                ];
                            }
                            
                            $check = db('material_list')->where([
                                'auto_id' => $value['fDetailID'],
                                'fInterId' => $head['fInterId'],
                                'type' => $type //单据类型
                            ])->find();
                            if($check){
                                if(!$check['status']){
                                    continue;//关闭状态，跳过
                                }
                                if($check['id']){
                                    $temp_ml_arr['id'] = $check['id'];
                                }
                            }
                            
                            $temp_sum_qty = db('temporary')->where([
                                'auto_id'=>$value['fDetailID'],
                                'order_list'=>$type==3?15:2,//15销售出库 2材料清单出库
                                'inv_id'=>$value['fItemId'],
                                'row_id'=>$value['fEntryId'],
                                'status'=>['IN',[0,1]]
                            ])->sum('quantity',0);
                            
                            if($temp_sum_qty>0){
                                $temp_ml_arr['status'] = 0;//关闭
                                $temp_ml_arr['close_time'] = date('Y-m-d', time());
                            }
                            
                            //获得推荐路径，在物料里
                            $wh_sh_arr = Inventory::getTjWhShByInvNumber($value['fItemId']);
                            if($wh_sh_arr){
                                $temp_ml_arr['warehouse_id'] = $wh_sh_arr['warehouse_id'];
                                $temp_ml_arr['tj_shelves_id'] = $wh_sh_arr['shelves_id'];
                            }
                            
                            $material_list_arr[] = $temp_ml_arr;
                        }
                    }
                }
                if($material_arr){
                    self::saveAll($material_arr,true);
                }
                if($material_list_arr){
                    $materialListModel = new MaterialList();
                    $materialListModel->saveAll($material_list_arr,true);
                }
            }
            //更新库存json文件
            //$apiWms = new Wms();
            //$apiWms->getMaterialList('add','./uploads/data/');
        }catch (Exception $e){
            if(stripos($e->getMessage(),'Duplicate')>0){
                preg_match_all("/'(.*?)'/", $e->getMessage(), $matches);
                $content = $matches[0];
                if(isset($content[0])){
                    exception($content[0].'存在相同行号记录');
                }
            }else{
                exception($e->getMessage());
            }
        }
    }
}
